<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Object-oriented programming II</title>
<link rel="stylesheet" href="/cfg/format.css" type="text/css">
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<meta name="keywords" content="PHP, learn PHP, OOP, object-oriented programming, programming, language">
<meta name="description" content="In this part of the PHP tutorial, we continue covering 
Object-oriented programming in PHP.">
<meta name="language" content="en">
<meta name="author" content="Jan Bodnar">
<meta name="distribution" content="global">

<script type="text/javascript" src="/lib/jquery.js"></script>
<script type="text/javascript" src="/lib/common.js"></script>

</head>

<body>

<div class="container">

<div id="wide_ad" class="ltow">
<script type="text/javascript"><!--
google_ad_client = "pub-9706709751191532";
/* 160x600, August 2011 */
google_ad_slot = "2484182563";
google_ad_width = 160;
google_ad_height = 600;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</div>

<div class="content">

<a href="/" title="Home">Home</a>&nbsp;
<a href="..">Contents</a>


<h1>Object-oriented programming II</h1>

<p>
In this chapter of the PHP tutorial, we continue description of the OOP 
in the PHP language. 
</p>

<div class="center">
<script type="text/javascript"><!--
google_ad_client = "ca-pub-9706709751191532";
/* top_horizontal */
google_ad_slot = "3327173442";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</div>

<h2>The static keyword</h2>

<p>
We can declare class properties and methods to be <code>static</code>.
The <code>static</code> properties and methods do not belong to the 
instance of the class. They belong to the class itself. They are accessible through
the scope resolution operator (::).
</p> 

<pre class="code">
&lt;?php

class Sys {
    public static function println($string) {
        echo "$string\n";
    }
}

Sys::println("PHP");
Sys::println("PERL");
Sys::println("Python");
Sys::println("Pike");

?&gt;
</pre>

<p>
In the above PHP script, we have a <code>static</code> println() 
method. It prints a string and starts a new line. This example
is inspired by the Java language. 
</p>

<pre class="explanation">
Sys::println("PHP");
</pre>

<p>
We do not need an object to call println() method. We call <code>static</code>
methods by specifying the class name, followed by double colon operator and the
method name.
</p>

<pre>
$ php static1.php 
PHP
PERL
Python
Pike
</pre>

<p>
This is the output of the script. 
</p>


<pre class="code">
&lt;?php

class Math {
    public static $PI = 3.14159265359;
}

echo Math::$PI . "\n";

?&gt;
</pre>

<p>
And now we have an example with a <code>static</code> variable. 
</p>

<pre class="explanation">
echo Math::$PI . "\n";
</pre>

<p>
We access the variable by specifying the class name, followed by the scope
resolution operator and the variable name. 
</p>

<h2>The final keyword</h2>

<p>
Final methods cannot be overriden and final classes cannot be extended.  The 
<code>final</code> keyword is a matter of design of the application.
Some classes should not be extended and some methods should not be overriden. 
This behaviour is enforced by the <code>final</code> keyword.
</p>


<pre class="code">
&lt;?php

class Base {

    final function say() {
        echo "Base class";
    }
}

class Derived extends Base {

    function say() {
        echo "Derived class";
    }
}

?&gt;
</pre>

<p>
This PHP script won't compile. We get an error "Cannot override final method Base::say()".
</p>


<pre class="code">
&lt;?php

final class Math {

    static function getPI() {
        return 3.141592;
    }
}

class DerivedMath extends Math {

    function say() {
        echo "DerivedMath class";
    }
}

?&gt;
</pre>

<p>
In the previous PHP script, we have a prototype base Math class. The sole purpose of this 
class is to provide some helpful methods and constants to the programmer. (In our case we have
only one method for simplicity reasons.) It is not created to be extended. To prevent uninformed
other programmers to derive from this class, the creators made the class <code>final</code>. 
If you try to run this PHP script, you get the following error: "Fatal error: Class DerivedMath may not 
inherit from final class (Math)".
</p>

<h2>Deep copy vs shallow copy</h2>

<p>
Copying of data is an important task in programming. Object is a composite data type in OOP. 
Member field in an object may be stored by value or by reference. Copying may be performed in
two ways. 
</p>

<p>
The <b>shallow copy</b> copies all values and references into a new instance. The data to which a
referece is pointing is not copied; only the pointer is copied. The new references
are pointing to the original objects. Any changes to the reference members affect both objects. 
</p>

<p>
The <b>deep copy</b> copies all values into a new instance. In case of members that are stored as
references a deep copy performs a deep copy of data, that is being referenced. A new copy of a referenced
object is created. And the pointer to the newly created object is stored. Any changes to those referenced
objects will not affect other copies of the object. Deep copies are fully replicated objects. 
</p>

<p>
In PHP, we have a <code>copy</code> keyword, which performs a shallow copy by default.
It calls the object's <code>__clone()</code> method. We can implement the method to create our 
custom deep copy. In PHP 5, all objects are assigned by reference.
</p>

<p>
The next two examples will perform a shallow and a deep copy on objects. 
</p>

<pre class="code">
&lt;?php

class Object {

    public $id;
    public $size;
    public $color;

    function __construct($id, $size, $color) {
        $this->id = $id;
        $this->size = $size;
        $this->color = $color;
    }
}

class Color {
    public $red;
    public $green;
    public $blue;

    function __construct($red, $green, $blue) {
        $this->red = $red;
        $this->green = $green;
        $this->blue = $blue;
    }
}

$color = new Color(23, 42, 223);

$object1 = new Object(23, "small", $color);
$object2 = clone $object1;

$object2->id++;
$object2->color->red = 255;
$object2->size = "big";

print_r($object1);
print_r($object2);

?&gt;
</pre>

<p>
In the above PHP script, we define two custom objects. Object and Color. The Object object
will have a reference to the Color object. 
</p>


<pre class="explanation">
$color = new Color(23, 42, 223);
</pre>

<p>
We create an instance of the Color object. 
</p>

<pre class="explanation">
$object1 = new Object(23, "small", $color);
</pre>

<p>
An instance of the Object object is created. It passes the
instance of the Color object to its constructor. 
</p>

<pre class="explanation">
$object2 = clone $object1;
</pre>

<p>
We perform a shallow copy of the Object object. 
</p>

<pre class="explanation">
$object2->id++;
$object2->color->red = 255;
$object2->size = "big";
</pre>

<p>
Here we modify the member fields of the cloned object. 
We increment the id, change the red part of the color object and
change the size to "big".
</p>



<pre class="explanation">
print_r($object1);
print_r($object2);
</pre>

<p>
We use the <code>print_r()</code> function to compare the results.
</p>

<pre>
$ php shallowcopy.php 
Object Object
(
    [id] => 23
    [size] => small
    [color] => Color Object
        (
            [red] => 255
            [green] => 42
            [blue] => 223
        )

)
Object Object
(
    [id] => 24
    [size] => big
    [color] => Color Object
        (
            [red] => 255
            [green] => 42
            [blue] => 223
        )

)
</pre>

<p>
We can see, that the ids are different. 23 vs 24. The size is different.
"small" vs "big". But the red part of the color object is same for both instances.
255. Changing member values of the cloned object did not affect the original object.
Changing members of the referenced object has affected the original object too. 
In other words, both objects refer to the same color object in memory.
</p>

<p>
To change this behaviour, we will do a deep copy next. 
</p>

<pre class="code">
&lt;?php

class Object {

    public $id;
    public $size;
    public $color;

    function __construct($id, $size, $color) {
        $this->id = $id;
        $this->size = $size;
        $this->color = $color;
    }

    function __clone() {
        $red = $this->color->red;
        $green = $this->color->green;
        $blue = $this->color->blue;
        $this->color = new Color($red, $green, $blue);
    }
}

class Color {
    public $red;
    public $green;
    public $blue;

    function __construct($red, $green, $blue) {
        $this->red = $red;
        $this->green = $green;
        $this->blue = $blue;
    }
}

$color = new Color(23, 42, 223);

$object1 = new Object(23, "small", $color);
$object2 = clone $object1;

$object2->id++;
$object2->color->red = 255;
$object2->size = "big";

print_r($object1);
print_r($object2);

?&gt;
</pre>

<p>
In this PHP script, we have implemented the <code>__clone()</code> method.
</p>


<pre class="explanation">
function __clone() {
    $red = $this->color->red;
    $green = $this->color->green;
    $blue = $this->color->blue;
    $this->color = new Color($red, $green, $blue);
}
</pre>

<p>
Inside the <code>__clone()</code> method, we copy the red, green and blue
member fields and create a new Color object. Now, the <b>$color</b> field points to 
a different Color object. 
</p>

<pre>
$ php deepcopy.php 
Object Object
(
    [id] => 23
    [size] => small
    [color] => Color Object
        (
            [red] => 23
            [green] => 42
            [blue] => 223
        )

)
Object Object
(
    [id] => 24
    [size] => big
    [color] => Color Object
        (
            [red] => 255
            [green] => 42
            [blue] => 223
        )

)
</pre>

<p>
Now the red part of the referenced Color object is not the same. The original object 
has retained its previous 23 value.
</p>

<h2>Exceptions</h2>

<p>
Exceptions are designed to handle the occurrence of exceptions, special conditions that
change the normal flow of program execution. Exceptions are raised or thrown, initiated. 
</p>

<p>
During the execution of our application,
many things might go wrong. A disk might get full and we cannot save our file.
An internet connection might go down and our application tries to connect to a site.
All these might result in a crash of our application. To prevent happening this,
we must cope with all possible errors that might occur. For this, we can use the exception handling.
</p>

<p>
Exceptions were only recently built into the PHP 5 language. Most PHP errors still use the 
old error reporting and not exceptions. With a <code>set_error_handler()</code> we
can do a workaround for this.
</p>

<pre class="code">
&lt;?php

set_error_handler("error_handler");

function error_handler($errno, $errstring, $errfile, $line, $trace) {
    throw new ErrorException($errstring, $errno, 0,  $errfile, $line);
}

try {
    $a = 0;
    $b = 32;
    $c = $b / $a;
} catch(ErrorException $e) {
   echo "Error occurred\n";
   echo $e->getMessage(), "\n";
}

?&gt;
</pre>

<p>
In the above PHP script, we intentionally divide a number by zero. This leads to an error.
The error is not an exception and is not caught by the <code>catch</code> keyword. 
</p>

<pre class="explanation">
set_error_handler("error_handler");
</pre>

<p>
The <code>set_error_handler()</code> function sets a user defined error handler function.
</p>


<pre class="explanation">
function error_handler($errno, $errstring, $errfile, $line, $trace) {
    throw new ErrorException($errstring, $errno, 0,  $errfile, $line);
}
</pre>

<p>
Inside the <code>set_error_handler()</code> function, we throw 
an <code>ErrorException</code>. This exception is later caught by
the <code>catch</code> keyword. 
</p>

<pre class="explanation">
try {
    $a = 0;
    $b = 32;
    $c = $b / $a;
}
</pre>

<p>
The code, that we are checking against an error is put inside the block following the
<code>try</code> keyword. 
</p>

<pre class="explanation">
} catch(Exception $e) {
   echo $e->getMessage();
}
</pre>

<p>
The <code>catch</code> keyword is used to 
catch an exception, which occurred. To find out more info,
we call the <code>getMessage()</code> method
on the exception object.  
</p>

<pre>
$ php zerodiv.php 
Error occurred
Division by zero
</pre>

<p>
This is the output of our PHP script. 
</p>

<p>
The <code>Exception</code> is a base class for all exceptions. We can create our
own exceptions derived from this base class. 
</p>


<pre class="code">
&lt;?php

define("LIMIT", 333);

class BigValueException extends Exception {

    public function __construct($message) {
        parent::__construct($message);
    }
}

$a = 34325;

try {
    if ($a > LIMIT) {
        throw new BigValueException("Exceeded the maximum value allowed\n");   
    }
} catch (BigValueException $e) {
    echo $e->getMessage();   
}

?&gt;
</pre>

<p>
Let's say, we have a situation in which we cannot deal with big numbers. 
</p>

<pre class="explanation">
define("LIMIT", 333);
</pre>

<p>
Numbers bigger than this constant are considered to be "big" by 
our PHP script. 
</p>

<pre class="explanation">
class BigValueException extends Exception {
</pre>

<p>
We have a <b>BigValueException</b> class. This class derives from the 
<code>Exception</code> class through the <code>extends</code> keyword.
</p>

<pre class="explanation">
public function __construct($message) {
    parent::__construct($message);
}
</pre>

<p>
Inside the constructor, we call the parent's constructor. 
</p>

<pre class="explanation">
if ($a > LIMIT) {
    throw new BigValueException("Exceeded the maximum value allowed\n");   
}
</pre>

<p>
If the value is bigger than the limit, we throw our custom exception.
We give the exception a message "Exceeded the maximum value allowed". 
</p>

<pre class="explanation">
} catch (BigValueException $e) {
    echo $e->getMessage();   
}
</pre>

<p>
We catch the exception and print its message to the console. 
</p>


<h2>Constructor oveloading</h2>

<p>
At the time of writing this tutorial (February 2010), constructor overloading
is not supported in PHP language. In other words, each class can only have one
constructor defined. Many programmers, that know Java or C# languages are looking for
a similar feature in PHP. There are two ways, how we can handle this. 
</p>

<p>
The first solution is based on the <code>func_get_args()</code> function.
The second solution uses a <b>factory pattern</b>.
</p>

<pre class="code">
&lt;?php

class Book {
    
    private $title = "not specified";
    private $author = "not specified";
    private $year = "not specified";

    public function __construct() {
        $args = func_get_args();
    
        foreach(array("title", "author", "year") as $item)
        {
            if(empty($args)) {
                break;
            }
    
            $this->$item = array_shift($args);
        }
    }
    
    public function __toString() {
        return "Author: $this->author\nTitle: $this->title\nPublished: $this->year\n\n";
    }
}

$book1 = new Book("Stephen Prata", "C Primer Plus");
echo $book1;

$book2 = new Book("Joshua Bloch", "Effective Java", 2008);  
echo $book2;

?&gt;
</pre>

<p>
In the above script, we have a <b>Book</b> class. We instantiate the
class with 2 and 3 parameters. 
</p>

<pre class="explanation">
private $author = "not specified";
private $title = "not specified";
private $year = "not specified";
</pre>

<p>
We have three member fields defined. Their initial value is "not specified".
</p>

<pre class="explanation">
$args = func_get_args();
</pre>

<p>
The <code>func_get_args()</code> function returns
an array comprising a function's argument list. So the idea is:
the code inside the constructor is dynamic, it depends on the 
arguments passed to it. 
</p>

<pre class="explanation">
foreach(array("title", "author", "year") as $item)
</pre>

<p>
We go through all member fields using the <code>foreach</code>
keyword.
</p>

<pre class="explanation">
$this->$item = array_shift($args);
</pre>

<p>
One of the most basic tasks in constructors is to initialize the member fields
of the class. This is done by the above code line. The <code>array_shift()</code>
function removes the first item from the array and returns it.
</p>

<pre class="explanation">
$book1 = new Book("Stephen Prata", "C Primer Plus");
...
$book2 = new Book("Joshua Bloch", "Effective Java", 2008);
</pre>

<p>
We have two different constructors. The first takes 2 parameters, the
second takes 3. 
</p>

<pre>
$ php constructors.php
Author: C Primer Plus
Title: Stephen Prata
Published: not specified

Author: Effective Java
Title: Joshua Bloch
Published: 2008

</pre>

<p>
This is the outcome of the script. 
</p>

<p>
The next code example simulates constructor overloading using the 
<b>factory pattern</b>. It is one of the creational patterns in OOP. 
The pattern creates objects without specifying the exact class of object 
that will be created. More generally, the term factory method is often 
used to refer to any method whose main purpose is creation of objects.
(from Wikipedia)
</p>


<pre class="code">
&lt;?php

class Cat {

    private $name = "unspecified";
    private $age = "unspecified";

    public static function withName($name) {
        $cat = new Cat();
        $cat->name = $name;

        return $cat;
    }

    public static function withAge($age) {
        $cat = new Cat();
        $cat->age = $age;

        return $cat;
    }

    public static function fullCat($name, $age) {
        $cat = new Cat();
        $cat->name = $name;
        $cat->age = $age;

        return $cat;
    }

    public function __toString() {
        return "Name: $this->name, Age: $this->age\n";
    }
}

$cici = Cat::withName("Cici");
echo $cici;

$missy = Cat::withAge(6);
echo $missy;

$lucky = Cat::fullCat("Lucky", 4);
echo $lucky;

?&gt;
</pre>

<p>
We have a <b>Cat</b> factory class in the above PHP script. 
It has three different static functions. Each of them returns a
specific cat object.
</p>

<pre class="explanation">
private $name = "unspecified";
private $age = "unspecified";
</pre>

<p>
We have two member fields. Their initial value is "unspecified". 
</p>


<pre class="explanation">
public static function withName($name) {
    $cat = new Cat();
    $cat->name = $name;

    return $cat;
}
</pre>

<p>
Here is a <b>withName()</b> static function. This function creates an instance 
of the <b>Cat</b> class. Set the name member field and returns the object. 
</p>

<pre class="explanation">
$cici = Cat::withName("Cici");
echo $cici;
</pre>

<p>
We create an instance of the cat with one of the factory methods. 
We echo the object. e.g. call the <code>__toString()</code> method of the
class.
</p>

<pre>
$ php factory.php 
Name: Cici, Age: unspecified
Name: unspecified, Age: 6
Name: Lucky, Age: 4
</pre>

<p>
The output of the script. 
</p>


<p>
In this part of the PHP tutorial, we continued the discussion of the object-oriented programming
in PHP. 
</p>

<div class="center"> 
<script type="text/javascript"><!--
google_ad_client = "pub-9706709751191532";
/* horizontal */
google_ad_slot = "1734478269";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script> 
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> 
</script> 
</div> 
<br> 


<div class="botNav, center">
<span class="botNavItem"><a href="/">Home</a></span> ‡ <span class="botNavItem"><a href="..">Contents</a></span> ‡
<span class="botNavItem"><a href="#">Top of Page</a></span>
</div>


<div class="footer">
<div class="signature">
<a href="/">ZetCode</a> last modified February 20, 2010  <span class="copyright">&copy; 2007 - 2013 Jan Bodnar</span>
</div>
</div>

</div> <!-- content -->

</div> <!-- container -->

</body>
</html>

